package cn.muqingfeng.api.request;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Map;

import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.toolbox.HttpHeaderParser;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

/**
 * @description 文件上传请求
 * @author <a href="mailto:zhongyang.zhao@downjoy.com">Barry.Zhao</a>
 * @time 2014-10-9 上午10:21:35
 * @version 7.0
 */
public class MultipartRequest<T> extends BaseGsonRequest<T> {

	private Listener<T> mResponseListener;
	private Class<T> mClazz;
	private Map<String, String> mParams;
	private Map<String, File> mFileParams;
	private String mContentType;

	public MultipartRequest(String url, Listener<T> responseListener, ErrorListener errorListener, Map<String, String> params, Map<String, File> fileParams,
			Class<T> clazz) {
		super(Method.POST, url, errorListener);
		this.mResponseListener = responseListener;
		this.mParams = params;
		this.mClazz = clazz;
		this.mFileParams = fileParams;
	}

	@Override
	protected Response<T> parseNetworkResponse(NetworkResponse response) {
		String responseStr;
		try {
			responseStr = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
		} catch (UnsupportedEncodingException e) {
			responseStr = new String(response.data);
		}
		try {
			Gson gson = createGson();
			T result = gson.fromJson(responseStr, mClazz);
			return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
		} catch (JsonSyntaxException e) {
			e.printStackTrace();
			return Response.error(new ParseError(e));
		}
	}

	@Override
	public byte[] getBody() throws AuthFailureError {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			Charset charset = Charset.forName(getParamsEncoding());
			MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT, null, charset);
			// 添加参数
			if (mParams != null && !mParams.isEmpty()) {
				for (Map.Entry<String, String> entry : mParams.entrySet()) {
					entity.addPart(entry.getKey(), new StringBody(entry.getValue(), charset));
				}
			}
			// 添加文件
			if (mFileParams != null && !mFileParams.isEmpty()) {
				for (Map.Entry<String, File> entry : mFileParams.entrySet()) {
					entity.addPart(entry.getKey(), new FileBody(entry.getValue()));
				}
			}
			mContentType = entity.getContentType().getValue();
			entity.writeTo(baos);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return baos.toByteArray();
	}

	@Override
	public String getBodyContentType() {
		return mContentType;
	}

	@Override
	protected void deliverResponse(T response) {
		if (mResponseListener != null) {
			mResponseListener.onResponse(response);
		}
	}

	@Override
	public Map<String, String> getHeaders() throws AuthFailureError {
		return mApiContext.getHeaders(mNeedLogin);
	}

	@Override
	protected Map<String, String> getParams() throws AuthFailureError {
		return mParams;
	}

}
